#include "net.h"

/**
 * @brief 用于监听端口并接收ACK包的线程函数
 * 
 * @param arg 参量表
 * @return void* 
 */
void *task_receive(void *arg)
{
    int sockfd = *(int *)arg;

    while(1)
    {
        char receive_message[256];
        size_t length = Recv(sockfd, receive_message, TCP_BUFFER_LENGTH, 0);
        if(strcmp("END", receive_message) == 0)
        {
            break;
        }
        if (length > 0)
        {
            receive_message[length] = 0;
            printf("message received: %s[%zu bytes]\n", receive_message, length);
        }
        else
        {
            printf("connection closed");
        }
    }
}

int main()
{
    // 服务器地址结构体变量
    struct sockaddr_in server_addr = {0};
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(TCP_SERVER_ADDRESS);
    server_addr.sin_port = htons(TCP_SERVER_PORT);
    // 服务器端套接字
    int server_sockfd;
    // 客户端地址结构体变量
    struct sockaddr_in client_addr;
    // 客户端地址结构体长度
    unsigned int client_addr_len = sizeof(struct sockaddr_in);;
    // 客户端套接字
    int client_sockfd;

    // 生成套接字并分配资源
    server_sockfd = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    // 刷新端口冷却时间
    int enable = 1;
    Setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
    // 套接字绑定端口
    Bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
    // 监听被绑定的端口
    Listen(server_sockfd, CONNECTION_NUMBER);
    // 接受来自客户端的连接请求
    client_sockfd = Accept(server_sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
    printf("Accept client %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

    // 创建收数据线程
    pthread_t thread_receive;
    if (pthread_create(&thread_receive, NULL, task_receive, (void *)&client_sockfd) != 0)
    {
        perror("pthread_create failed.\n");
        exit(1);
    }

    // 本来的发送线程
    while(1)
    {
        char send_message[256];
        scanf("%s", send_message);
        printf("send message: %s[%zu bytes]\n", send_message, strlen(send_message));
        Send(client_sockfd, send_message, strlen(send_message), 0);
        if(strcmp("END", send_message) == 0)
        {
            break;
        }
    }

    // 销毁线程
    if (pthread_cancel(thread_receive) != 0)
    {
        printf("[main thread] pthread_cancel failed.\n");
        exit(1);
    }

    // 关闭套接字
    Shutdown(client_sockfd, SHUT_RDWR);
    Shutdown(server_sockfd, SHUT_RDWR);

    return 0;
}
